package org.budo.netty.servlet.server.handler.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.Cookie;

import org.budo.netty.servlet.util.TimeUtil;

/**
 * @author li
 */
public abstract class AbstractBudoServletResponse implements BudoServletResponse {
    private String contentType;

    private Integer contentLength = 0;

    /**
     * 默认 200
     */
    private int status = 200;

    private String characterEncoding = "UTF-8";

    private Map<String, String> headers = new HashMap<String, String>();

    private BudoServletOutputStream outputStream = new BudoServletOutputStream();

    private Locale locale;

    @Override
    public Locale getLocale() {
        return this.locale;
    }

    @Override
    public void setLocale(Locale locale) {
        this.locale = locale;
    }

    @Override
    public String encodeUrl(String url) {
        return url;
    }

    @Override
    public void sendRedirect(String location) throws IOException {
        this.setStatus(302);

        this.setHeader("Location", location);
    }

    @Override
    public void setHeader(String name, String value) {
        this.headers.put(name, value);
    }

    @Override
    public void addHeader(String name, String value) {
        this.headers.put(name, value);
    }

    @Override
    public void setIntHeader(String name, int value) {
        this.setHeader(name, "" + value);
    }

    @Override
    public void addIntHeader(String name, int value) {
        this.setHeader(name, "" + value);
    }

    @Override
    public int getStatus() {
        return this.status;
    }

    @Override
    public void setStatus(int status) {
        this.status = status;
    }

    @Override
    public Collection<String> getHeaders(String name) {
        String value = this.headers.get(name);
        return Arrays.asList(value);
    }

    @Override
    public String getHeader(String name) {
        return this.headers.get(name);
    }

    @Override
    public Collection<String> getHeaderNames() {
        return this.headers.keySet();
    }

    @Override
    public String getCharacterEncoding() {
        return this.characterEncoding;
    }

    @Override
    public void setCharacterEncoding(String characterEncoding) {
        this.characterEncoding = characterEncoding;
    }

    @Override
    public String getContentType() {
        return this.contentType;
    }

    public Map<String, String> getHeaders() {
        return this.headers;
    }

    public long getContentLength() {
        return this.contentLength;
    }

    @Override
    public void setContentLength(int contentLength) {
        this.contentLength = contentLength;
        this.setIntHeader("Content-Length", contentLength);
    }

    @Override
    public boolean containsHeader(String name) {
        return this.headers.containsKey(name);
    }

    @Override
    public void setDateHeader(String name, long date) {
        this.setHeader(name, TimeUtil.dateHeader(date));
    }

    @Override
    public void setContentType(String contentType) {
        this.setHeader("Content-Type", contentType);
        this.contentType = contentType;

        String charset = "charset=";
        int i = contentType.indexOf(charset);
        if (i >= 0) {
            String characterEncoding = contentType.substring(i + charset.length());
            this.setCharacterEncoding(characterEncoding);
        }
    }

    /**
     * Cannot call getWriter(), getOutputStream() already called
     */
    @Override
    public BudoServletOutputStream getOutputStream() throws IOException {
        return this.outputStream;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return new PrintWriter(this.getOutputStream());
    }

    @Override
    public void addCookie(Cookie cookie) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeRedirectUrl(String url) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void addDateHeader(String name, long date) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setStatus(int statuScode, String statusMessage) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int getBufferSize() {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setBufferSize(int size) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void resetBuffer() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isCommitted() {
        throw new UnsupportedOperationException("#203 this=" + this);
    }

    @Override
    public void reset() {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setContentLengthLong(long len) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeURL(String url) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeRedirectURL(String url) {
        throw new UnsupportedOperationException();
    }
}